package cn.wolfcode.luowowo.member.service.impl;

import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.cache.util.RedisKeys;
import cn.wolfcode.luowowo.common.exception.LogicException;
import cn.wolfcode.luowowo.common.util.AssertUtil;
import cn.wolfcode.luowowo.common.util.Consts;
import cn.wolfcode.luowowo.common.util.PhoneUtil;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.mapper.UserInfoMapper;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import cn.wolfcode.luowowo.member.vo.UserVO;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.UUID;

@Service
public class UserInfoServiceImpl implements IUserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Reference
    private IUserInfoRedisService userInfoRedisService;

    @Override
    public UserInfo get(Long id) {
        return userInfoMapper.selectByPrimaryKey(id);

    }

    @Override
    public boolean checkUnique(String phone) {

        int count = userInfoMapper.selectUniqueByPhone(phone);
        return count>0;
    }
    String verifykey = null;
    @Override
    public void sendVerifyCode(String phone) throws LogicException{
        AssertUtil.hasLength(phone,"手机号不能为空");
        if(userInfoRedisService.isEmpty(RedisKeys.FREQUENCY_CODE.join(verifykey))){
            verifykey = null;
        }
        if (verifykey == null || "".equals(verifykey)) {
            //发短信操作实现频率控制, 一分钟只能发3次 redis的key标记:  value次数
            verifykey = UUID.randomUUID().toString().replaceAll("-", "");
            userInfoRedisService.frequencyControl(RedisKeys.FREQUENCY_CODE.join(verifykey));
        }
        System.out.println(verifykey+"  xxxxxxxxx");
        Long num = userInfoRedisService.getVerifyValue(RedisKeys.FREQUENCY_CODE.join(verifykey));
        if(num <= 0L) {
            throw new LogicException("验证码1分钟内申请不可以超过3次");
        }
        //1.获得短信验证码
        String code = UUID.randomUUID().toString().replaceAll("-", "")
                .substring(0, 4);
        //2.创造一个短信对象
        StringBuilder stringBuilder = new StringBuilder(100);
        stringBuilder.append("尊敬的用户您好，您的短信验证码是").append(code).append(" ,请您在")
                .append(Consts.VERIFY_CODE_VAI_TIME).append("分钟内使用");
        //模拟发送短信
        System.out.println(stringBuilder);
        //将验证码存入缓存
        userInfoRedisService.setVerifyCode(phone, code);

    }

    @Override
    public void userRegist(String phone, String nickname, String password, String rpassword, String verifyCode) throws LogicException {

        //1 判断参数是否为空
        AssertUtil.hasLength(phone,"手机号码不能为空");
        AssertUtil.hasLength(nickname,"昵称不能为空");
        AssertUtil.hasLength(password,"密码不能为空");
        AssertUtil.hasLength(rpassword,"确认密码不能为空");
        AssertUtil.hasLength(verifyCode,"手机验证码不能为空");
        //2 判断密码是否一致
        AssertUtil.isEquals(password,rpassword,"两次输入的密码不一致");
        //3 判断手机格式是否正确
        PhoneUtil.phoneMatch(phone);
        //4 判断手机号是否唯一
        if(this.checkUnique(phone)){
            throw new LogicException("该手机号已经被注册了");
        }
        //5 短信验证码是否一致
        String code = userInfoRedisService.getVerifyCode(phone);
        if(code == null || !code.equalsIgnoreCase(verifyCode)){
            throw new LogicException("验证码输入有误或不存在");
        }
        //6 用户注册
        UserInfo userInfo = new UserInfo();
        userInfo.setHeadImgUrl("/images/default.jpg");
        userInfo.setLevel(1);
        userInfo.setNickname(nickname);
        userInfo.setPassword(password);
        userInfo.setPhone(phone);
        userInfo.setState(UserInfo.STATE_NORMAL);
        userInfoMapper.insert(userInfo);

    }

    @Override
    public String userLogin(String username, String password) throws LogicException {

        //分布式登录操作步骤
        //0. 判断参数是否为空
        AssertUtil.hasLength(username,"用户账号不能为空");
        AssertUtil.hasLength(password,"用户密码不能为空");
        //1. 获取参数username和password，作为条件，通过sql查询用户对象
        UserInfo user = userInfoMapper.selectUserByUsernameAndPassword(username, password);
        //2. 根据查到的user对象判断是否存在，如果不存在，提示登录失败，如果存在，执行下一步操作
        if(user == null){
            throw new LogicException("账号或密码不存在");
        }
        //3. 登录成功后，定义一个变量名为token，值作为UUID创建随机值
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //4. 将随机生成的token值作为redis中的key,登录的用户对象作为redis中value值，缓存到redis数据库中，同时设置时长
        userInfoRedisService.setToken(token,user);

        return token;

    }

    @Override
    public List<UserInfo> list() {
        return userInfoMapper.selectAll();
    }

    @Override
    public List<Long>  getFocusUserIdList(Long id) {
        return userInfoMapper.findFocusUserIdList(id);
    }

    @Override
    public List<Long> getFanUserIdList(Long id) {
        return userInfoMapper.findFansUserIdList(id);
    }

    @Override
    public UserInfo updateUserInfo(UserInfo userInfo) {
          userInfoMapper.updateByPrimaryKey(userInfo);
          return userInfo;
    }

    @Override
    public void updateHeadImgUrl(UserInfo userInfo) throws LogicException{
        userInfoMapper.updateHeadImgUrl(userInfo);
    }

    @Override
    public void updatePassword(String vPassword,String password, Long userId) throws LogicException{
        UserInfo userInfo = userInfoMapper.selectByPrimaryKey(userId);
        AssertUtil.hasLength(vPassword,"原密码不能为空");
        AssertUtil.hasLength(password,"密码不能为空");
        AssertUtil.isEquals(userInfo.getPassword(),vPassword,"原密码不正确");
//        AssertUtil.isEquals(vPassword,password,"两次密码不一致");
        userInfoMapper.updatePasswordById(password,userId);
    }

    @Override
    public void udpateEmail(String email, Long userId) throws LogicException{
        AssertUtil.hasLength(email,"邮箱不能为空");
        userInfoMapper.updateEmailById(email,userId);
    }

    @Override
    public void authentication(String phone, String verifyCode) throws LogicException{
        AssertUtil.hasLength(phone,"手机号不能为空");
        AssertUtil.hasLength(verifyCode,"验证码不能为空");
        String code = userInfoRedisService.getVerifyCode(phone);
        AssertUtil.hasLength(code,"手机号不正确");
        AssertUtil.isEquals(verifyCode,code,"验证码不正确");
    }

    @Override
    public void updatePhone(String phone, Long userId) throws LogicException{
        userInfoMapper.updatePhoneById(phone,userId);
    }


    @Override
    public void addBlackUser(Long userId, Long blackUserId) throws LogicException{
//        userInfoMapper.addBlackUser(userId,blackUserId);
        userInfoRedisService.addBlackUser(userId,blackUserId);
    }

    @Override
    public void deleteBlackUser(Long userId, Long blackUserId) {
        userInfoMapper.deleteBlackUserByUserId(userId,blackUserId);
        userInfoRedisService.removeBlackUser(userId,blackUserId);
    }

    @Override
    public List<UserVO> blackUserList(Long userId) {
        return userInfoRedisService.blackUserList(userId);
    }

    @Override
    public List<Long> blackUserIdList(Long userId) {
        return userInfoMapper.blackUserIdList(userId);
    }

    @Override
    public void persistenceBlackUser(Long userId, Long blackUserId) {
        Long id = userInfoMapper.isExistsBlackUserIdByUserId(userId,blackUserId);
        if(id == null){
            userInfoMapper.addBlackUser(userId,blackUserId);
        }
    }
}
